/*
================================================================================
	Plik: f_and.c
--------------------------------------------------------------------------------
	Autorzy: Piotr Zdunek, Mateusz Słowikowski, Krzysztof Wiąckowski
	Projekt:Model mikrokontrolera AVR
	Kompilator: avr-gcc-4.3.5
	Doc: doxygen 1.7.4
--------------------------------------------------------------------------------
	Zawiera:
--------------------------------------------------------------------------------
	Komentarze:
================================================================================
*/

/*! \file f_and.c
 *
 * \brief Plik opisujący funkcję AND.
 *
 */

#include "types.h"
#include "mem_abs.h"

void F_AND(void){
/*!  void F_AND(void){}
	 *  \n \n
	 *  \ref pageand \n
	 */

#if DEBUG_MODE
	printf("Function AND.");
#endif
//Pobranie rejestru flagowego z pamięci
	uint8_t FLAGS;
	FLAGS = GetFlagRegister();

    uint8_t Rd=(getMEMC(getPC()) & 0x00F0) >> 4;						//identyfikacja numeru rejestru arg. 1
    uint8_t RdMSB = (((getMEMC(getPC()) & 0x0F00) >> 8) & 0b0001)<<4;
    Rd = RdMSB + Rd;

    uint8_t Rr=(getMEMC(getPC()) & 0x000F);								//identyfikacja numeru rejestru arg. 2
    uint8_t RrMSB = (((getMEMC(getPC()) & 0x0F00) >> 8) & 0b0010)<<3;
    Rr = RrMSB + Rr;

    uint8_t Rd_val = getRegister(Rd) % MAX_DATA_VAL;					//pobranie zawartosci rejestru arg 1
    uint8_t Rr_val = getRegister(Rr) % MAX_DATA_VAL;					//pobranie zawartosci rejestru arg 2
    uint8_t R = (Rd_val & Rr_val);										//obliczenie wyniku

	//----------USTAWIENIA REJESTRU FLAG-----------

    ClearFlagRegisterBit(FLAG_V); 										// wyzerowanie flagi V

    if( ( (Rd & 0x80) >> 7) == 0 && ((R & 0x80) >> 7) == 1) 			// jeśli MSB Rd == 0 i MSB R == 1 to zmieniamy
    	SetFlagRegisterBit(FLAG_N);										// bo nastąpiła zmiana MSB
  	else
    	ClearFlagRegisterBit(FLAG_N);

	if( R == 0 ) SetFlagRegisterBit( FLAG_Z );							//ustwienie flagi Z
	else ClearFlagRegisterBit( FLAG_Z );

	if( (GetFlagRegisterStatus(FLAG_N) ^ GetFlagRegisterStatus(FLAG_V)) == 1 ){  	//ustwienie flagi S
		SetFlagRegisterBit(FLAG_S);
	}
	else ClearFlagRegisterBit(FLAG_S);

	//PrintFlagRegisterStatus();											//wypisanie zawartosci rejestru flag
	setRegister(Rd,R);													//Zapisanie wartosci rejestru do pamięci
    incPC();															//zwi�kszenie licznika rozkaz�w
}
/*! \page pageand Opis działania funkcji AND
 *
 *	\dontinclude f_and.c
 *
 *	\section sec_and1 Operacje rejestrowe oraz arytmetyczno-logiczne
 *	1. Pobranie rejestru flagowego z pamięci:
 *	\skipline FLAGS
 *	2. Identyfikacja numeru rejestru arg. 1:
 *	\skipline Rd
 *	3. Identyfikacja numeru rejestru arg. 2:
 *	\skipline Rr
 *	4. Pobranie zawartosci rejestru arg 1:
 *	\skipline Rd
 *	5. Pobranie zawartosci rejestru arg 2:
 *	\skipline Rr
 *	6. Obliczenie wyniku:
 *	\skipline R
 *
 *	\section sec_and2 Operacje na flagach
 *	1. Wyzerowanie flagi V
 *	\skipline FLAG_V
 *	2. Ustawienie flagi N
 *	\line if
 *	\until ClearFlagRegisterBit
 *	3. Ustawienie flagi Z
 *	\line if
 *	\until ClearFlagRegisterBit
 *	4. Ustawienie flagi S
 *	\line if
 *	\until ClearFlagRegisterBit
 *	5. Zapisanie nowej zawartości Rd
 *	\skipline setRegister
 *	6. Zwiększenie PC
 *	\skipline incPC
 *
 *	\section sec_and3 Kod źródłowy funkcji
 *
 *	\include f_and.c
 *
 */
